#include "rdpcore.h"
#include <QScreen>
#include <QDebug>
#include <QGuiApplication>
#include <QPixmap>
#include <QImage>
#include <QBuffer>
#include <QTime>

rdpCore::rdpCore(bool debug)
{
    isDebug = debug;
}

// 设置配置参数
void rdpCore::setConfig(int x, int y, int width, int height, int b)
{
    this->indexX = x;
    this->indexY = y;
    this->serverWidth = width;
    this->serverHeight = height;
    this->bit = b;

    serverBlockWidth = serverWidth / indexX;
    serverBlockHeight = serverHeight / indexY;

    QScreen *screen = QGuiApplication::primaryScreen();
    clientWidth = screen->geometry().width();
    clientHeight = screen->geometry().height();

    clientBlockWidth = clientWidth / indexX;
    clientBlockHeight = clientHeight / indexY;

    qDebug() << "客户端信息：屏幕宽度" << clientWidth << " 屏幕高度：" << clientHeight << " 图像块宽度："<<clientBlockWidth << " 图像块高度："<<clientBlockHeight;
    qDebug() << "服务端信息：显示宽度" << serverWidth << " 显示高度：" << serverHeight << " 图像块宽度："<<serverBlockWidth << " 图像块高度："<<serverBlockHeight;

    pixmapDataArr.clear();
    for(int i = 0; i < x * y ; i++)
    {
        pixmapDataArr.append(QByteArray());
    }
}

// 获取位于[x,y]处的图像块数据
QByteArray rdpCore::getBlockMapData(int x, int y)
{
//    QByteArray mapData;
//    if(!pixmapDataArr.at(y * indexX + x).isEmpty())
//    {
//        mapData.resize(2);
//        mapData[0] = x;
//        mapData[1] = y;
//        mapData.append(pixmapDataArr.at(y * indexX + x));
//    }
//    return mapData;
    return pixmapDataArr.at(y * indexX + x);
}

// 获进行屏幕截图，并将有变化的位图块更新存储下来
void rdpCore::takeScreenShot()
{
    if(checkEnv())
    {
        // 截取全屏图像
        QScreen *screen = QGuiApplication::primaryScreen();
        QPixmap pixmap = screen->grabWindow(
                    0,
                    0,
                    0,
                    clientWidth,
                    clientHeight);
        // 调整图片大小以适应服务端显示参数(缩放)
        pixmap = pixmap.scaled(serverWidth, serverHeight);

        // 将图像分割成[x,y]的图像块，并比较历史数据，将变化的图像存入图像块列表
        for(int y = 0; y < indexY ; y ++)
        {
            for(int x = 0; x < indexX ; x ++)
            {
                QPixmap blockPixmap = pixmap.copy(x * serverBlockWidth,
                                                  y * serverBlockHeight,
                                                  serverBlockWidth,
                                                  serverBlockHeight);

                // 转换图片色阶
                QImage originImage = blockPixmap.toImage();
                QImage dstImage;
                if(bit == 8){
                    dstImage = originImage.convertToFormat(QImage::Format_Grayscale8);
                }else if(bit == 16){
                    dstImage = originImage.convertToFormat(QImage::Format_RGB16);
                }else if(bit == 24){
                    dstImage = originImage.convertToFormat(QImage::Format_RGB666);
                }else if(bit == 32){
                    dstImage = originImage.convertToFormat(QImage::Format_RGB32);
                }else{
                    dstImage = originImage;
                }

                // 如果开启调试模式则保存图片到文件
                if(isDebug)
                {
                    saveImage(dstImage, x ,y);
                }
                // 将图像转换成QByteArrary，并压缩为png图片
                QByteArray imageData;
                QBuffer buffer(&imageData);
                buffer.open(QIODevice::WriteOnly);
                dstImage.save(&buffer, "png");
                // 比较图片是否有变化，如果有变化拷贝到结果的mapData返回
                if(!cmpBlockMap(x , y , imageData))
                {
                    pixmapDataArr.replace(y * indexX + x , imageData);
                }else
                {
                    pixmapDataArr.replace(y * indexX + x , QByteArray());
                }
            }
        }

    }
}

// *********************** 以下是私有函数 ****************************

// 检查环境变量
bool rdpCore::checkEnv()
{
    return (indexX > 0 && indexY > 0
            && serverWidth > 0 && serverHeight > 0
            && serverBlockWidth > 0 && serverHeight > 0
            && clientWidth > 0 && clientHeight > 0
            && clientBlockWidth > 0 && clientBlockHeight > 0)
            ? true : false;
}

//// 保存pixmap位图 到文件
//void rdpCore::savePixmap(QPixmap pixmap, int x ,int y)
//{
//    QString path = QString("%1/%2_[%3,%4].png")
//            .arg(QCoreApplication::applicationDirPath())
//            .arg(QTime::currentTime().toString("hh_mm_ss"))
//            .arg(x)
//            .arg(y);
//    pixmap.save(path);
//}

// 保存image图片到文件
void rdpCore::saveImage(QImage image, int x ,int y)
{
    QString path = QString("%1/%2_[%3,%4].png")
            .arg(QCoreApplication::applicationDirPath())
            .arg(QTime::currentTime().toString("hh_mm_ss"))
            .arg(x)
            .arg(y);
    image.save(path);
}

// 比较图片数据和pixmapDataArr中上一次图片数据是否相同
bool rdpCore::cmpBlockMap(int x, int y, QByteArray pixmapData)
{
    if(pixmapDataArr.at(y * indexX + x) == pixmapData)
        return true;
    else
        return false;
}
